package com.yunchang.springboot.utils;

import org.apache.commons.lang3.StringUtils;

import javax.xml.datatype.XMLGregorianCalendar;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 时间工具类
 *
 * @author wanglongwei
 * @data 2019/5/7 17:44
 */
public class DateUtil {
    /**
     * 时间格式
     */
    private final static String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";

    /**
     * 获取当前时间
     *
     * @param pattern
     * @return
     */
    public static String getDate(String pattern) {
        //设置时间格式
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return dateFormat.format(new Date());
    }

    /**
     * 获取当前时间默认时间格式
     *
     * @return
     */
    public static String getDate() {
        return getDate(yyyy_MM_dd_HH_mm_ss);
    }


    /**
     * 获取今天的日期
     *
     * @param pattern 时间格式
     * @return
     */
    public static String getTodayDate(String pattern) {
        //设置时间格式
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(new Date());
    }

    /**
     * 获取当前年份
     *
     * @return
     */
    public static Integer getYear() {
        Calendar cale = Calendar.getInstance();
        return cale.get(Calendar.YEAR);
    }

    /**
     * 获取当前月份
     *
     * @return
     */
    public static Integer getMonth() {
        Calendar cale = Calendar.getInstance();
        return cale.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取未来 第 past 天的日期
     *
     * @param past
     * @return
     */
    public static String getFetureDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String result = format.format(today);
        return result;
    }

    /**
     * =======
     * 获取多少月之后的日期 时区为（GMT-8）
     *
     * @param past
     * @return
     */
    public static String getFutureMonthDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + past);
        Date date = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        format.setTimeZone(TimeZone.getTimeZone("GMT-8"));
        return format.format(date);
    }

    /**
     * 获取下一个月的第一天日期
     *
     * @param dateStr
     * @param format
     * @return
     */
    public static String getFirstDayOfNextMonth(String dateStr, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            Date date = sdf.parse(dateStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.add(Calendar.MONTH, 1);
            return sdf.format(calendar.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取下一个月的七号日期
     *
     * @param month
     * @param format
     * @return
     */
    public static String getSeventhDayOfNextMonth(String month, String format) {
        Integer monthLength = 7;
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            month = month.trim();
            if (month.length() == monthLength) {
                month = month + "-01";
            }
            Date date = sdf.parse(month);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.DAY_OF_MONTH, 7);
            calendar.add(Calendar.MONTH, 1);
            return sdf.format(calendar.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取指定日期多少月之后的日期
     *
     * @param past
     * @return
     */
    public static String dateToFutureMonthDate(String date, int past) throws ParseException {
        String basePattern = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat format = new SimpleDateFormat(basePattern.substring(0, date.length()));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(format.parse(date));
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + past);
        Date calendarTime = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT-8"));
        return simpleDateFormat.format(calendarTime);
    }

    /**
     * 获取未来 第 past 天的日期 零点的时间
     *
     * @param past
     * @return
     */
    public static Date getFutureDateDay(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * Date转换为LocalDateTime
     *
     * @param date
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        //An instantaneous point on the time-line.(时间线上的一个瞬时点。)
        Instant instant = date.toInstant();
        //A time-zone ID, such as {@code Europe/Paris}.(时区)
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
//        //2018-03-27T14:07:32.668
//        System.out.println(localDateTime.toString());
//        //2018-03-27 14:48:57.453
//        System.out.println(localDateTime.toLocalDate() + " " + localDateTime.toLocalTime());
        //This class is immutable and thread-safe.@since 1.8
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //2018-03-27 14:52:57
        return localDateTime;
    }

    /**
     * 获取未来 第 past 天的日期 二十三点 五十九分 五十九秒 的时间
     *
     * @param past
     * @return
     */
    public static Date getFutureDateDayLastTime(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 获取未来 第 past 天的日期
     *
     * @param past
     * @return
     */
    public static String getFutureDateDayReturnString(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String timeFormat = sdf.format(calendar.getTime());
        return timeFormat;
    }

    /**
     * 获取未来 第 past 天的时间
     *
     * @param past
     * @return
     */
    public static String getFutureDateTime(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        Date time = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss);
        return simpleDateFormat.format(time);
    }

//    /*
//    字符串转日期
//    *
//    * */
//    public static Date strToDate(String str) {
//        DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime();
//        DateTime dateTime = ((org.joda.time.format.DateTimeFormatter) dateTimeFormatter).parseDateTime(str);
//        Date reportDate = dateTime.toDate();
//        return reportDate;
//    }

    /**
     * 获取给定时间月份上一个月的第一天
     *
     * @param date
     * @return
     */
    public static String getFirstTimeMonth(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的第一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, -1);
        cale.set(Calendar.DAY_OF_MONTH, cale.getMinimum(Calendar.DATE));
        return format.format(cale.getTime());
    }

    /**
     * 获取指定日期的未来第amount月份的第一天，amount为负数时则为之前的月份
     *
     * @param date
     * @param amount
     * @return
     */
    public static String getFirstDayByMonth(Date date, int amount) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的第一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getMinimum(Calendar.DATE));
        return format.format(cale.getTime());
    }


    /**
     * 获取指定日期的未来第amount月份的最后一天，amount为负数时则为之前的月份
     *
     * @param date
     * @param amount
     * @return
     */
    public static String getLastDayByMonth(Date date, int amount) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的第一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getMaximum(Calendar.DATE));
        return format.format(cale.getTime());
    }


    /**
     * 给定月份上一个月的最后一天
     *
     * @param date
     * @return
     */
    public static String getLastTimeMonth(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的最后一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, -1);
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DATE));
        return format.format(cale.getTime());
    }

    /**
     * 将ISO8601时间转为西八区时间
     *
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMT_8(String time, String pattern) throws ParseException {
        if (StringUtil.isBlank(time)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(pattern);
        Date parse = df.parse(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT-8"));
        return dateFormat.format(parse);
    }


    /**
     * 将ISO8601时间转为零时区时间 时间格式为：yyyy-MM-dd HH:mm:ss
     *
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMT(String time, String pattern) throws ParseException {
        if (StringUtil.isBlank(time)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(pattern);
        Date parse = df.parse(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return dateFormat.format(parse);
    }

    /**
     * 将ISO8601时间转为西八区时间
     *
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMT_8ByOtherPattern(String time, String pattern) throws ParseException {
        if (StringUtil.isBlank(time)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(pattern);
        Date parse = df.parse(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT-8"));
        return dateFormat.format(parse);
    }

    /**
     * 将ISO8601时间转为西八区时间
     *
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMTByOtherPattern(String time, String pattern) throws ParseException {
        if (StringUtil.isBlank(time)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(pattern);
        Date parse = df.parse(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT-8"));
        return dateFormat.format(parse);
    }

    /**
     * 将ISO8601时间转为UTC时间
     *
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToUTCByOtherPattern(String time, String pattern) throws ParseException {
        if (StringUtil.isBlank(time)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(pattern);
        Date parse = df.parse(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT-8"));
        return dateFormat.format(parse);
    }


    /**
     * 将ISO8601时间转为东八区时间
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMT8(String time) throws ParseException {
        return ISO8601ToGMT8(time, "yyyy-MM-dd'T'HH:mm:ssXXX");
    }

    /**
     * 将ISO8601时间转为东八区时间
     *
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMT8(String time, String pattern) throws ParseException {
        if (StringUtil.isBlank(time)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(pattern);
        Date parse = df.parse(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return dateFormat.format(parse);
    }

    /**
     * 将ISO8601时间转为西八区时间
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMT_8(String time) throws ParseException {
        return ISO8601ToGMT_8(time, "yyyy-MM-dd'T'HH:mm:ssXXX");
    }


    /**
     * 将ISO8601时间转为零时区时间
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMT(String time) throws ParseException {
        return ISO8601ToGMT(time, "yyyy-MM-dd'T'HH:mm:ssXXX");
    }


    public static String ISO8601ToGMT_8ByOtherPatternTwo(String time) throws ParseException {
        return ISO8601ToGMT_8(time, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 将ISO8601时间转化为零时区时间 时间格式为：yyyy-MM-dd HH:mm:ss
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMTByOtherPatternTwo(String time) throws ParseException {
        return ISO8601ToGMT(time, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 将ISO8601时间转为西八区时间
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMT_8ByOtherPattern(String time) throws ParseException {
        return ISO8601ToGMT_8ByOtherPattern(time, "yyyy/MM/dd HH:mm:ss");
    }


    /**
     * 将ISO8601时间转为零时区时间  时间格式为：yyyy/MM/dd HH:mm:ss
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static String ISO8601ToGMTByOtherPattern(String time) throws ParseException {
        return ISO8601ToGMT_8ByOtherPattern(time, "yyyy/MM/dd HH:mm:ss");
    }

    /**
     * 获取当前ISO8601时间---默认零时区
     *
     * @return
     */
    public static String getISO8601Timestamp() {
        return getISO8601Timestamp("");
    }

    /**
     * 获取当前ISO8601时间
     *
     * @param timeZone -8:西八区    +8:东八区
     * @return
     */
    public static String getISO8601Timestamp(String timeZone) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(TimeZone.getTimeZone("GMT" + timeZone));
        return df.format(new Date());
    }

    /**
     * 时间转为ISO8601格式
     *
     * @param date
     * @param timeZone -8:西八区    +8:东八区
     * @return
     */
    public static String timeToISO8601(Date date, String timeZone) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(TimeZone.getTimeZone("GMT" + timeZone));
        return df.format(date);
    }

    /**
     * 时间转为ISO8601格式 零时区
     *
     * @param date
     * @return
     */
    public static String timeToISO8601ZeroTimeZone(Date date) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(TimeZone.getTimeZone("GMT-8"));
        return df.format(date);
    }

    /**
     * 时间转为ISO8601格式
     *
     * @param date
     * @return
     */
    public static String timeToISO8601(Date date) {
        return timeToISO8601(date, "+8");
    }

    /**
     * 时间转为ISO8601格式
     *
     * @param date
     * @param timeZone -8:西八区    +8:东八区
     * @return
     */
    public static String timeToISO8601(String date, String timeZone) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT" + timeZone));
        Date parse = dateFormat.parse(date);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(TimeZone.getTimeZone("GMT" + timeZone));
        return df.format(parse);
    }

    /**
     * 时间转为ISO8601格式---默认零时区
     *
     * @param date
     * @return
     */
    public static String timeToISO8601(String date) throws ParseException {
        return timeToISO8601(date, "+8");
    }

    /**
     * 时间转为ISO8601格式---默认零时区
     *
     * @param date
     * @return
     */
    public static String timeToISO8601ByOtherFormat(String date) throws ParseException {
        return timeToISO8601ByOtherFormat(date, "+8");
    }

    /**
     * 时间转为ISO8601格式
     *
     * @param date
     * @param timeZone -8:西八区    +8:东八区
     * @return
     */
    public static String timeToISO8601ByOtherFormat(String date, String timeZone) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT" + timeZone));
        Date parse = dateFormat.parse(date);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(TimeZone.getTimeZone("GMT" + timeZone));
        return df.format(parse);
    }

    /**
     * 时间字符串判断大小
     *
     * @param leftTime
     * @param rightTime
     * @return 1:左边的大于右边的   0:左边等于右边       -1:左边小于右边
     */
    public static int compateTime(String leftTime, String rightTime) throws ParseException {
        if (StringUtil.isBlank(leftTime) || StringUtil.isBlank(rightTime)) {
            throw new RuntimeException("时间字符串判断大小错误，时间不能为空");
        }
        String basePattern = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat leftSimpleDateFormat = new SimpleDateFormat(basePattern.substring(0, leftTime.length()));
        leftSimpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        long left = leftSimpleDateFormat.parse(leftTime).getTime();
        SimpleDateFormat rightSimpleDateFormat = new SimpleDateFormat(basePattern.substring(0, rightTime.length()));
        rightSimpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        long right = rightSimpleDateFormat.parse(rightTime).getTime();
        return Long.compare(left, right);
    }

    /**
     * 根据日期获取未来的日期
     *
     * @param date
     * @param past
     * @return
     */
    public static String dateToFutureDate(String date, int past) throws ParseException {
        String basePattern = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat format = new SimpleDateFormat(basePattern.substring(0, date.length()));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(format.parse(date));
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        Date time = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return simpleDateFormat.format(time);
    }

    /**
     * 根据日期获取未来的日期
     *
     * @param date
     * @param past
     * @return
     */
    public static Date getDateToFutureDate(String date, int past) throws ParseException {
        String basePattern = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat format = new SimpleDateFormat(basePattern.substring(0, date.length()));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(format.parse(date));
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        return calendar.getTime();
    }

    /**
     * 英式日期转普通日期
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static String usDateToDate(String date) throws ParseException {
        if (StringUtil.isBlank(date)) {
            return null;
        }
        DateFormat sdf = new SimpleDateFormat("MMM dd, yyyy", Locale.US);
        Date parse = sdf.parse(date);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return simpleDateFormat.format(parse);
    }

    /**
     * 获取广告获取时间
     *
     * @return
     */
    public static String getAdvReportTime() {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String now = DateUtil.getISO8601Timestamp("-8");
        now = now.substring(0, now.indexOf("T"));
        long dif = 0;//减一天
        try {
            dif = df.parse(now).getTime() - 86400 * 1000;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Date date = new Date();
        date.setTime(dif);
        return df.format(date);
    }

    /**
     * 获取本月第一天
     *
     * @return
     */
    public static String getMonthFirstDay() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, 0);
        return format.format(calendar.getTime());
    }

    /**
     * 给定月份的最后一天
     * cjw  2019 12 04 修改了解析时间问题
     *
     * @param date
     * @return
     */
    public static Date getLastTimeMonthByDate(Date date, int amount) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的最后一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DATE));
        return cale.getTime();
    }

    /**
     * 获取给定时间月份的第一天
     * cjw  2019 12 04 修改了解析时间问题
     *
     * @param date
     * @return
     */
    public static Date getFirstTimeMonthByDate(Date date, int amount) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的第一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getMinimum(Calendar.DATE));
        return cale.getTime();
    }

    /**
     * 获取给定时间月份的第一天
     *
     * @param date
     * @return
     */
    public static String getFirstTimeMonthByString(Date date, int amount) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的第一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getMinimum(Calendar.DATE));
        return format.format(cale.getTime()) + " 00:00:00";
    }

    /**
     * 给定月份的最后一天
     *
     * @param date
     * @return
     */
    public static String getLastTimeMonthByString(Date date, int amount) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的最后一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DATE));
        return format.format(cale.getTime()) + " 23:59:59";
    }

    /**
     * 获取给定时间月份的第一天 时间转为ISO8601格式
     *
     * @param date
     * @param timeZone
     * @param pattern
     * @return
     */
    public static String getMonthFirstDayByString(Date date, int amount, String timeZone, String pattern, String area) {
        int hour = 0;
        List<String> NORTH_AMERICA_REGION = Arrays.asList("BR", "CA", "MX", "US");
        List<String> EUROPE_REGION = Arrays.asList("AE", "DE", "EG", "ES", "FR", "GB", "IN", "IT", "SA", "TR");
        List<String> FAR_EAST_REGION = Arrays.asList("SG", "AU", "JP");
        if (!StringUtils.isEmpty(area)) {
            if (NORTH_AMERICA_REGION.contains(area)) {
                hour = 16;
            }
            if (EUROPE_REGION.contains(area)) {
                hour = 7;
            }
            if (FAR_EAST_REGION.contains(area)) {
                hour = -1;
            }
        }
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的第一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getMinimum(Calendar.DATE));
        cale.set(Calendar.HOUR_OF_DAY, 0 + hour);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        format.setTimeZone(TimeZone.getTimeZone(timeZone));
        return format.format(cale.getTime());
    }

    /**
     * 获取给定日期的指定月份的最后一天的 时间转为ISO8601格式
     *
     * @param date
     * @param timeZone
     * @param pattern
     * @return
     */
    public static String getMonthLastDayByDate(Date date, int amount, String timeZone, String pattern, String area) {
        int hour = 0;
        List<String> NORTH_AMERICA_REGION = Arrays.asList("BR", "CA", "MX", "US");
        List<String> EUROPE_REGION = Arrays.asList("AE", "DE", "EG", "ES", "FR", "GB", "IN", "IT", "SA", "TR");
        List<String> FAR_EAST_REGION = Arrays.asList("SG", "AU", "JP");
        if (!StringUtils.isEmpty(area)) {
            if (NORTH_AMERICA_REGION.contains(area)) {
                hour = 16;
            }
            if (EUROPE_REGION.contains(area)) {
                hour = 7;
            }
            if (FAR_EAST_REGION.contains(area)) {
                hour = -1;
            }
        }
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的最后一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DATE));
        cale.set(Calendar.HOUR_OF_DAY, 23 + hour);
        cale.set(Calendar.MINUTE, 59);
        cale.set(Calendar.SECOND, 59);
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        format.setTimeZone(TimeZone.getTimeZone(timeZone));
        return format.format(cale.getTime());
    }

    /**
     * 获取给定时间月份的第一天
     *
     * @param date
     * @return 返回ISO
     */
    public static Date getMonthFirstDayByDate(Date date, int amount) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的第一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getMinimum(Calendar.DATE));
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        return cale.getTime();
    }

    /**
     * 获取给定日期的指定月份的最后一天的
     *
     * @param date
     * @return
     */
    public static Date getMonthLastDayByDate(Date date, int amount) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的最后一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DATE));
        cale.set(Calendar.HOUR_OF_DAY, 23);
        cale.set(Calendar.MINUTE, 59);
        cale.set(Calendar.SECOND, 59);
        return cale.getTime();
    }

    /**
     * 获取给定日期的指定月份的第一天或最后一天的任何时间，可以指定时分秒
     *
     * @param date
     * @param amount
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    public static Date getMonthLastDayByDate(Date date, int amount, int hour, int minute, int second, String firstOrLast) {
        String first = "first";
        String last = "last";
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        // 获取时间月份的最后一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, amount);
        if (!StringUtils.isEmpty(firstOrLast)) {
            if (firstOrLast.equals(first)) {
                cale.set(Calendar.DAY_OF_MONTH, cale.getMinimum(Calendar.DATE));
            }
            if (last.equals(firstOrLast)) {
                cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DATE));
            }
        }
        cale.set(Calendar.HOUR_OF_DAY, hour);
        cale.set(Calendar.MINUTE, minute);
        cale.set(Calendar.SECOND, second);
        return cale.getTime();
    }

    public static String getNowDate() {
        LocalDate today = LocalDate.now();
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String dateStr = today.format(fmt);
        return dateStr;
    }

    public static String getNowDateTime() {
        LocalDateTime today = LocalDateTime.now();
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String dateStr = today.format(fmt);
        return dateStr;
    }

    /**
     * 获取指定日期的前一天
     *
     * @param specifiedDay
     * @return
     * @author wangz
     */
    public static String getBeforeDay(String specifiedDay) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day - 1);

        String dayBefore = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
        return dayBefore;
    }

    /**
     * 获取指定日期的后一天
     *
     * @param specifiedDay
     * @return
     * @author wangz
     */
    public static String getAfterDay(String specifiedDay) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day + 1);

        String dayAfter = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
        return dayAfter;
    }


    /**
     * 根据开始时间和结束时间返回时间段内的时间集合
     *
     * @param beginDate
     * @param endDate
     * @return List
     */
    public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
        List<Date> lDate = new ArrayList<Date>();
        // 把开始时间加入集合
        lDate.add(beginDate);
        Calendar cal = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(beginDate);
        boolean bContinue = true;
        while (bContinue) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (endDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        // 把结束时间加入集合
        lDate.add(endDate);
        return lDate;
    }

    /**
     * 将yyyy-MM-dd HH:mm:ss格式的字符串日期转为LocalDateTime类型的日期对象
     * @param dateString
     * @return
     */
    public static LocalDateTime getLocalDateTime(String dateString){
        if (!dateString.matches("^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)\\s+([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$")){
            return null;
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return LocalDateTime.parse(dateString,dateTimeFormatter);
    }

    /**
     * 将XMLGregorianCalendar转为LocalDateTime
     * @param xmlGregorianCalendar
     * @return
     */
    public static LocalDateTime transXMLGregorianCalendarToLocalDateTime(XMLGregorianCalendar xmlGregorianCalendar){
        return LocalDateTime.of(xmlGregorianCalendar.getYear(),xmlGregorianCalendar.getMonth(),xmlGregorianCalendar.getDay(),xmlGregorianCalendar.getHour(),xmlGregorianCalendar.getMinute(),xmlGregorianCalendar.getSecond());
    }

    /**
     * 将LocalDateTime类型的日期对象转为yyyy-MM-dd HH:mm:ss格式的字符串日期
     * @param localDateTime
     * @return
     */
    public static String transLocalDateTimeToDateString(LocalDateTime localDateTime){
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return localDateTime.format(dateTimeFormatter);
    }
}
